package com.sgl.gk.controller;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sg.comm.common.Ret;
import com.sg.comm.opcuav2.NodeDTOV2;
import com.sg.comm.opcuav2.OpcUaReadReqV2;
import com.sg.comm.opcuav2.batch.BatchReadDTO;
import com.sg.comm.opcuav2.single.ReadByNodeReq;
import com.sg.comm.service.OpcUaServiceV2;
import com.sg.comm.service.SerialPortService;
import com.sgl.common.utils.StringUtils;
import com.sgl.gk.controller.vo.GkProductionLineVo;
import com.sgl.gk.controller.vo.GkStationConfigurationVo;
import com.sgl.gk.controller.vo.GkStationVo;
import com.sgl.gk.domain.*;
import com.sgl.gk.domain.plc.Node;
import com.sgl.gk.domain.plc.OpcUa;
import com.sgl.gk.domain.plc.OpcUaList;
import com.sgl.gk.mapper.*;
import com.sgl.gk.service.GkStationService;
import com.sgl.gk.tools.OpcUATool;
import com.sgl.gk.tools.ReadOpcUaNodeInfoTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author:xuenci
 * @date:2023/5/18 18:32
 **/
@Transactional
@RestController
@Slf4j
public class AdvancedTaskScheduleController {

    @Autowired
    GkStationEventMapper gkStationEventMapper;

    @Autowired
    GkStationConfigurationMapper gkStationConfigurationMapper;

    @Autowired
    GkStationConfigurationConnectMapper gkStationConfigurationConnectMapper;

    @Autowired
    GkStationConfigurationValuesMapper gkStationConfigurationValuesMapper;

    @Autowired
    GkStationMapper gkStationMapper;

    @Autowired
    GkProductMapper gkProductMapper;

    @Autowired
    GkProductionLineMapper gkProductionLineMapper;

    @Autowired
    GkStatisticsMapper gkStatisticsMapper;

    @Autowired
    GkReservedInfoMapper gkReservedInfoMapper;

    @Autowired
    GkEquipmentMapper gkEquipmentMapper;

    @DubboReference(version = "1.0.0", url = "dubbo://127.0.0.1:20880", check = false)
    private OpcUaServiceV2 opcUaServiceV2;

    @DubboReference(version = "1.0.0", url = "dubbo://127.0.0.1:20880", check = false)
    private SerialPortService serialPortService;

    @Autowired
    GkSignalCommunicationMapper gkSignalCommunicationMapper;

    @Autowired
    GkShowStationInfoMapper gkShowStationInfoMapper;

    @Autowired
    GkSettingMapper gkSettingMapper;


    public void AdvancedToTask() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    try {
                        judgeJDBC();
                        OpcUaReadReqV2 opcUaReqV2 = new OpcUaReadReqV2();
                        Ret<BatchReadDTO> batchReadDTORet = opcUaServiceV2.consumeData(opcUaReqV2);
                        if (batchReadDTORet.getData() != null) {
                            if (batchReadDTORet.getData().getUid() == null) {
                                continue;
                            }
                            log.info("剩余保存事件：{}", batchReadDTORet.getData().getSaveCnt());
                            String uid = batchReadDTORet.getData().getUid();
                            GkSignalCommunication gkSignalCommunication = gkSignalCommunicationMapper.selectInfoByCommunicationProtocol(uid);
                            GkStation gkStation = new GkStation();
                            gkStation.setSignalCommunicationId(gkSignalCommunication.getId());
                            List<GkStationVo> gkStationVos = gkStationMapper.list(gkStation);
                            if (CollUtil.isEmpty(gkStationVos)) {
                                log.error("未找到相对应工位");
                                continue;
                            }
                            List<NodeDTOV2> dtoList = batchReadDTORet.getData().getDtoList();
                            List<Long> stationIds = gkStationVos.stream().map(GkStationVo::getId).collect(Collectors.toList());
                            List<GkStationEvent> gkStationEventList = gkStationEventMapper.selectInfosByStationIds(stationIds);
                            // 提取出相对应产线保存的事件信息
                            gkStationEventList = gkStationEventList.stream().filter(gkStationEvent -> gkStationEvent.getConditionValue().equals("16")).collect(Collectors.toList());
                            if (CollUtil.isEmpty(gkStationEventList)) {
                                log.error("未找到对应事件信息");
                                continue;
                            }
                            List<Long> conditionConfigIds = gkStationEventList.stream().map(GkStationEvent::getConditionConfigurationId).collect(Collectors.toList());
                            // 相对应的Request_data信息
                            List<GkStationConfiguration> conditionConfigInfos = gkStationConfigurationMapper.selectInfoByIds(conditionConfigIds);
                            for (NodeDTOV2 nodeDTOV2 : dtoList) {
                                for (GkStationConfiguration conditionConfigInfo : conditionConfigInfos) {
                                    String nodeName = "data_pc_plc.plc_request." + conditionConfigInfo.getVariableName();
                                    if (nodeDTOV2.getDisplayName().equals(nodeName)) {
                                        for (GkStationEvent gkStationEvent : gkStationEventList) {
                                            if (gkStationEvent.getConditionConfigurationId().longValue() == conditionConfigInfo.getId().longValue()) {
                                                GkStation gkStation1 = gkStationMapper.selectInfoById(gkStationEvent.getStationId());
                                                List<GkProductionLineVo> gkProductionLineVos = gkProductionLineMapper.selectInfoByIds(Collections.singletonList(gkStation1.getProductionLineId()));
                                                String conditionStationId = gkStationEvent.getConditionStationId();
                                                String[] split = conditionStationId.split(",");
                                                // 需要读取的工位id
                                                List<Long> saveOrScanningStationIds = new ArrayList<>();
                                                for (String s : split) {
                                                    saveOrScanningStationIds.add(Long.parseLong(s));
                                                }
                                                List<NodeDTOV2> saveNodeList = nodeDTOV2.getSaveNodeList();
                                                new Thread(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        log.info("保存{}工位数据", gkStationEvent.getConditionStationId());
                                                        saveConfigurationValue(gkProductionLineVos, gkStationEvent, saveOrScanningStationIds, Collections.singletonList(gkSignalCommunication), saveNodeList);
                                                    }
                                                }).start();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }
                }
            }
        }).start();
    }

    /**
     * 保存读取的工位变量信息
     *
     * @param gkProductionLineVos      所有产线信息
     * @param gkStationEvent           保存的事件信息
     * @param saveOrScanningStationIds 需要保存的工位id
     * @param gkSignalCommunications   所有通讯信息
     */
    private void saveConfigurationValue(List<GkProductionLineVo> gkProductionLineVos, GkStationEvent gkStationEvent,
                                        List<Long> saveOrScanningStationIds, List<GkSignalCommunication> gkSignalCommunications, List<NodeDTOV2> nodeDTOV2List) {
        List<GkStation> saveStationInfos = gkStationMapper.selectInfosByIds(saveOrScanningStationIds);
        List<GkStationConfigurationVo> saveConfigurationInfos = gkStationConfigurationMapper.selectInfoByType2StationIds(saveOrScanningStationIds);
        Map<Long, List<GkStationConfigurationVo>> saveConfigurationInfoMap = saveConfigurationInfos.parallelStream().collect(Collectors.groupingBy(GkStationConfigurationVo::getStationId));
        GkStation gkStation = gkStationMapper.selectInfoById(gkStationEvent.getStationId());

//        List<ConfigValueAndConfigConnectVo> configValueAndConfigConnectVos = gkStationConfigurationValuesMapper.selectAllInfoAndConfigInfo();
//        configValueAndConfigConnectVos = configValueAndConfigConnectVos.stream().filter(configvalue -> !StringUtils.isEmpty(configvalue.getValue())).collect(Collectors.toList());
        Date date = new Date();
        // 获取最新的工位保存数据的连接表id
        Long maxConnectId = new Long(0l);
        for (GkProductionLineVo gkProductionLineVo : gkProductionLineVos) {
            if (gkStation.getProductionLineId().longValue() == gkProductionLineVo.getId().longValue()) {
                // 只添加一次连接表id
                GkStationConfigurationConnect gkStationConfigurationConnect = new GkStationConfigurationConnect();
                gkStationConfigurationConnect.setStationId(gkStation.getId());
                gkStationConfigurationConnect.setProductLineId(gkProductionLineVo.getId());
                gkStationConfigurationConnect.setProductLineName(gkProductionLineVo.getName());
                gkStationConfigurationConnect.setResult(-1);
                gkStationConfigurationConnect.setCreateAt(date);
                gkStationConfigurationConnect.setLastModifyAt(date);
                gkStationConfigurationConnectMapper.add(gkStationConfigurationConnect);
                maxConnectId = gkStationConfigurationConnect.getId();
//                maxConnectId = 2737l;
            }
        }
        // 合格与不合格标识  0 为没有不合格  1  为有不合格
        int flag = 0;
        // 总成码
        String assemblyCode = new String();
        // 追溯码
        String traceabilityCode = new String();
        String productName = new String();
        List<GkStationConfigurationValues> gkStationConfigurationValuesList = new ArrayList<>();
        int size = saveStationInfos.size();
        int index = 0;
        Long connectId = 0l;
        List<String> values = new ArrayList<>();
        List<Long> connectIds = new ArrayList<>();
        for (GkStation saveStationInfo : saveStationInfos) {
            if (saveStationInfo.getSignalCommunicationId() != null) {
                index += 1;
                for (GkSignalCommunication gkSignalCommunication : gkSignalCommunications) {
                    if (saveStationInfo.getSignalCommunicationId().longValue() == gkSignalCommunication.getId().longValue()) {

                        if (nodeDTOV2List == null) {
                            log.error("当前{}返回值为空", saveStationInfo.getName());
                            continue;
                        }

                        List<GkStationConfigurationVo> saveConfigurationInfoList = saveConfigurationInfoMap.get(saveStationInfo.getId());
                        for (NodeDTOV2 nodeDTOV2 : nodeDTOV2List) {
                            for (GkStationConfigurationVo gkStationConfigurationVo : saveConfigurationInfoList) {
                                // 拼接nodeName
                                String nodeName = "";
                                for (GkProductionLineVo gkProductionLineVo : gkProductionLineVos) {
                                    if (gkProductionLineVo.getId().longValue() == saveStationInfo.getProductionLineId().longValue()) {
                                        // 配置数据源。因为总成装配线的OP110等数据在Data里面拿取数据
                                        // todo 事件数据源的读取
                                        if (StringUtils.isNotEmpty(gkStationEvent.getDataSource())) {
                                            nodeName = gkStationEvent.getDataSource() + "." + ((saveStationInfo.getCode() == null || saveStationInfo.getCode().equals("")) ? saveStationInfo.getCode() : (saveStationInfo.getCode() + ".")) + gkStationConfigurationVo.getVariableName();
                                        } else if (!StringUtils.isEmpty(saveStationInfo.getDataSource())) {
                                            nodeName = saveStationInfo.getDataSource() + "." + ((saveStationInfo.getCode() == null || saveStationInfo.getCode().equals("")) ? saveStationInfo.getCode() : (saveStationInfo.getCode() + ".")) + gkStationConfigurationVo.getVariableName();
                                        } else {
                                            nodeName = gkProductionLineVo.getCode() + "." + ((saveStationInfo.getCode() == null || saveStationInfo.getCode().equals("")) ? saveStationInfo.getCode() : (saveStationInfo.getCode() + ".")) + gkStationConfigurationVo.getVariableName();
                                        }
                                    }
                                }
                                if (nodeDTOV2.getDisplayName().equals(nodeName.trim())) {
                                    String value = OpcUATool.getValue(nodeDTOV2);
                                    for (int i = 0; i < 6; i++) {
                                        if (gkStationConfigurationVo.getVariableName().toLowerCase().equals("barcode" + (i == 0 ? "" : i)) && !StringUtils.isEmpty(value)) {
                                            values.add(value);
                                        }
                                    }
                                    // 根据名称找到对应的最新值
                                    GkStationConfigurationValues stationConfigurationValues = new GkStationConfigurationValues();
                                    stationConfigurationValues.setStationConfigurationId(gkStationConfigurationVo.getId());
                                    stationConfigurationValues.setValue(value);
                                    stationConfigurationValues.setStationConfigurationConnectId(maxConnectId);
                                    stationConfigurationValues.setCreateAt(date);
                                    stationConfigurationValues.setLastModifyAt(date);
                                    gkStationConfigurationValuesList.add(stationConfigurationValues);
                                    // 判断生产是否合格
                                    if (gkStationConfigurationVo.getVariableName().equals("existence")) {
                                        // existence判定位0或者空时表示为正常生产工件不存在
                                        if (StringUtils.isEmpty(value) || value.equals("0") || value.equals("00") || value.equals("0.0")) {
                                            // 工件不存在
                                            flag = 0;
                                        }
                                        if (value.equals("3") || value.equals("03") || value.equals("3.0")) {
                                            // 标定模式
                                            flag = 3;
                                        }
                                        // existence只要是2或5那就判定为不合格
                                        if (value.equals("2") || value.equals("02") || value.equals("2.0")) {
                                            // 不合格零部件
                                            flag = 2;
                                        }
                                        if (value.equals("5") || value.equals("05") || value.equals("5.0")) {
                                            // 不合格零部件
                                            flag = 5;
                                        }
                                        if (value.equals("1") || value.equals("01") || value.equals("1.0")) {
                                            // 不合格零部件
                                            flag = 1;
                                        }
                                        if (value.equals("4") || value.equals("04") || value.equals("4.0")) {
                                            // 不合格零部件
                                            flag = 4;
                                        }
                                    }
                                    // 变量显示名称为总成条码的则是总成码
                                    if (gkStationConfigurationVo.getDisplayName().trim().equals("总成条码")) {
                                        assemblyCode = value;
                                    }
                                    // 变量显示名称为追溯条码的则是追溯条码
                                    if (gkStationConfigurationVo.getDisplayName().trim().equals("追溯条码")) {
                                        traceabilityCode = value;
                                    }
                                }
                                if (nodeDTOV2.getDisplayName().equals("DB_RECIPE.ProductType")) {
                                    productName = OpcUATool.getValue(nodeDTOV2);
                                }
                            }
                        }
                    }
                }
            } else {
                log.error(saveStationInfo.getName() + "未绑定通讯");
            }
        }
        if (CollUtil.isNotEmpty(values)) {
            connectIds = gkStationConfigurationValuesMapper.selectAllConnectIds(values);
            connectIds = connectIds.stream().distinct().collect(Collectors.toList());
        }
        // 匹配到值把添加的connect删除 并且改变需要保存值的connectId
        if (CollUtil.isNotEmpty(connectIds)) {
            List<GkStationConfigurationConnect> gkStationConfigurationConnects = gkStationConfigurationConnectMapper.selectInfoByIds(connectIds.toArray(new Long[0]));
            // 未完成的conn
            List<GkStationConfigurationConnect> noOkConn = new ArrayList<>();
            // 已完成的conn
            List<GkStationConfigurationConnect> isOkConn = new ArrayList<>();
            for (GkStationConfigurationConnect gkStationConfigurationConnect : gkStationConfigurationConnects) {
                if (gkStationConfigurationConnect.getIsOk() == null) {
                    noOkConn.add(gkStationConfigurationConnect);
                } else if (gkStationConfigurationConnect.getIsOk() == 0) {
                    noOkConn.add(gkStationConfigurationConnect);
                } else {
                    isOkConn.add(gkStationConfigurationConnect);
                }
            }
            // 有未完成的conn就进行合并  没有就进行复制
            if (CollUtil.isNotEmpty(noOkConn)) {
                connectId = noOkConn.get(noOkConn.size() - 1).getId();
                for (GkStationConfigurationConnect configurationConnect : noOkConn) {
                    if (configurationConnect.getId().longValue() > connectId.longValue()) {
                        connectId = configurationConnect.getId();
                    }
                }
                Long finalConnectId = connectId;
                connectIds = noOkConn.stream().map(GkStationConfigurationConnect::getId).filter(id -> id.longValue() != finalConnectId.longValue()).distinct().collect(Collectors.toList());
                // 合并前先删除已创建的conn
                gkStationConfigurationConnectMapper.deleteById(maxConnectId);

                if (CollUtil.isNotEmpty(connectIds)) {
                    List<GkStationConfigurationValues> gkStationConfigurationValues = gkStationConfigurationValuesMapper.selectByStationConfigurationConnectIds(connectIds);
                    List<GkStationConfigurationValues> gkStationConfigurationValuesList1 = new ArrayList<>();
                    for (GkStationConfigurationValues gkStationConfigurationValue : gkStationConfigurationValues) {
                        gkStationConfigurationValue.setStationConfigurationConnectId(connectId);
                        gkStationConfigurationValuesList1.add(gkStationConfigurationValue);
                    }
                    gkStationConfigurationValues = gkStationConfigurationValuesList1;
                    gkStationConfigurationValuesMapper.editListConnectId(gkStationConfigurationValues);
                    gkStationConfigurationConnectMapper.deleteByIds(connectIds);
                }
                for (GkStationConfigurationValues stationConfigurationValues : gkStationConfigurationValuesList) {
                    stationConfigurationValues.setStationConfigurationConnectId(connectId);
                }
                List<Long> configIds = gkStationConfigurationValuesList.stream().map(GkStationConfigurationValues::getStationConfigurationId).collect(Collectors.toList());
                SaveDeleteConfig(configIds, connectId);
                int row = gkStationConfigurationValuesMapper.deleteByConfigIdsAndConnectId(configIds, connectId);
                maxConnectId = connectId;
            } else if (CollUtil.isNotEmpty(isOkConn)) {
                // 找到需要进行复制的保存信息，及返修模式
                connectId = isOkConn.get(isOkConn.size() - 1).getId();
                for (GkStationConfigurationConnect configurationConnect : isOkConn) {
                    if (configurationConnect.getId().longValue() > connectId.longValue()) {
                        connectId = configurationConnect.getId();
                    }
                }
                // 找到保存信息值，进行复制
                List<GkStationConfigurationValues> gkStationConfigurationValues = gkStationConfigurationValuesMapper.selectByStationConfigurationConnectId(connectId);
                List<GkStationConfigurationValues> gkStationConfigurationValuesList1 = new ArrayList<>();
                Date date1 = new Date();
                Map<Long, List<GkStationConfigurationValues>> collect = gkStationConfigurationValues.parallelStream().collect(Collectors.groupingBy(GkStationConfigurationValues::getStationConfigurationId));
                if (CollUtil.isNotEmpty(collect)) {
                    for (Long aLong : collect.keySet()) {
                        List<GkStationConfigurationValues> gkStationConfigurationValuesList2 = collect.get(aLong);
                        if (CollUtil.isNotEmpty(gkStationConfigurationValuesList2)) {
                            GkStationConfigurationValues stationConfigurationValues = gkStationConfigurationValuesList2.stream().max(Comparator.comparing(GkStationConfigurationValues::getId)).get();
                            gkStationConfigurationValuesList1.add(stationConfigurationValues);
                            List<Long> deleteOldValueIds = gkStationConfigurationValuesList2.stream().filter(gkStationConfigurationValues1 -> gkStationConfigurationValues1.getId().longValue() != stationConfigurationValues.getId().longValue()).map(GkStationConfigurationValues::getId).collect(Collectors.toList());
                            if (CollUtil.isNotEmpty(deleteOldValueIds)) {
                                int row = gkStationConfigurationValuesMapper.deleteByIds(deleteOldValueIds);
                            }
                        }
                    }
                }
                gkStationConfigurationValues = gkStationConfigurationValuesList1;
                for (GkStationConfigurationValues gkStationConfigurationValue : gkStationConfigurationValues) {
                    gkStationConfigurationValue.setStationConfigurationConnectId(maxConnectId);
                    gkStationConfigurationValue.setCreateAt(date1);
                    gkStationConfigurationValue.setLastModifyAt(date1);
                }
                gkStationConfigurationValuesMapper.saveList(gkStationConfigurationValues);
                for (GkStationConfigurationValues stationConfigurationValues : gkStationConfigurationValuesList) {
                    stationConfigurationValues.setStationConfigurationConnectId(maxConnectId);
                }
                List<Long> configIds = gkStationConfigurationValuesList.stream().map(GkStationConfigurationValues::getStationConfigurationId).collect(Collectors.toList());
                SaveDeleteConfig(configIds, maxConnectId);
                int row = gkStationConfigurationValuesMapper.deleteByConfigIdsAndConnectId(configIds, maxConnectId);
            }
        }
        if (flag == 0) {
            // 不存在工件
            GkStationConfigurationConnect configurationConnect = new GkStationConfigurationConnect();
            configurationConnect.setId(maxConnectId);
            configurationConnect.setProductName(productName);
            configurationConnect.setLastModifyAt(new Date());
            if (StringUtils.isNotEmpty(assemblyCode)) {
                configurationConnect.setAssemblyCode(assemblyCode);
            }
            if (StringUtils.isNotEmpty(traceabilityCode)) {
                configurationConnect.setTraceabilityCode(traceabilityCode);
                configurationConnect.setIsOk(1);
                configurationConnect.setModels("");
                configurationConnect.setResult(-1);
            }
            gkStationConfigurationConnectMapper.edit(configurationConnect);
        } else if (flag == 3) {
            // 标定模式
            GkStationConfigurationConnect configurationConnect = new GkStationConfigurationConnect();
            configurationConnect.setId(maxConnectId);
            configurationConnect.setProductName(productName);
            configurationConnect.setLastModifyAt(new Date());
            if (StringUtils.isNotEmpty(assemblyCode)) {
                configurationConnect.setAssemblyCode(assemblyCode);
            }
            if (StringUtils.isNotEmpty(traceabilityCode)) {
                configurationConnect.setTraceabilityCode(traceabilityCode);
                configurationConnect.setIsOk(1);
                configurationConnect.setModels("标定模式");
                configurationConnect.setResult(-1);
            }
            gkStationConfigurationConnectMapper.edit(configurationConnect);
        } else
            // 不合格改变状态
            if (flag == 2 || flag == 5) {
                // 修改数据追溯状态
                GkStationConfigurationConnect configurationConnect = new GkStationConfigurationConnect();
                configurationConnect.setId(maxConnectId);
                configurationConnect.setProductName(productName);
                configurationConnect.setLastModifyAt(new Date());
                if (StringUtils.isNotEmpty(assemblyCode)) {
                    configurationConnect.setAssemblyCode(assemblyCode);
                }
                if (StringUtils.isNotEmpty(traceabilityCode)) {
                    configurationConnect.setTraceabilityCode(traceabilityCode);
                    configurationConnect.setIsOk(1);
                    configurationConnect.setResult(0);
                    if (flag == 2) {
                        configurationConnect.setModels("正常生产");
                    } else {
                        configurationConnect.setModels("返修模式");
                    }
                }
                gkStationConfigurationConnectMapper.edit(configurationConnect);

            } else if (flag == 1 || flag == 4) {
                // 工件正常生产合格和返修合格
                GkStationConfigurationConnect configurationConnect = new GkStationConfigurationConnect();
                configurationConnect.setId(maxConnectId);
                configurationConnect.setProductName(productName);
                if (StringUtils.isNotEmpty(assemblyCode)) {
                    configurationConnect.setAssemblyCode(assemblyCode);
                }
                if (StringUtils.isNotEmpty(traceabilityCode)) {
                    configurationConnect.setTraceabilityCode(traceabilityCode);
                    configurationConnect.setIsOk(1);
                    configurationConnect.setResult(1);
                    if (flag == 1) {
                        configurationConnect.setModels("正常生产");
                    } else {
                        configurationConnect.setModels("返修模式");
                    }
                }
                configurationConnect.setLastModifyAt(new Date());
                gkStationConfigurationConnectMapper.edit(configurationConnect);
            }
//        log.info("进入保存，保存内容为：{}", JSONUtil.toJsonStr(gkStationConfigurationValuesList));
        if (gkStationConfigurationValuesList.size() <= 0) {
            gkStationConfigurationConnectMapper.deleteById(maxConnectId);
        }
        if (gkStationConfigurationValuesList.size() > 0) {
//            log.info("匹配保存的值：{}", JSONUtil.toJsonStr(gkStationConfigurationValuesList));
            List<Long> saveConfigIds = gkStationConfigurationValuesList.stream().map(GkStationConfigurationValues::getStationConfigurationId).collect(Collectors.toList());
            gkStationConfigurationValuesMapper.deleteByConfigIdsAndConnectId(saveConfigIds, maxConnectId);
            SaveDeleteConfig(saveConfigIds, maxConnectId);
            gkStationConfigurationValuesMapper.saveList(gkStationConfigurationValuesList);
        }
    }


    /**
     * 数据统计数据采集
     */

    public void dataStatisticsTask() {
        // todo 2023.2.17版直接线程错误结束
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                        judgeJDBC();
                        List<GkStatistics> gkStatistics = gkStatisticsMapper.toDayInfo();
                        List<GkSignalCommunication> gkSignalCommunications = gkSignalCommunicationMapper.list(null);
                        List<GkSetting> list = gkSettingMapper.list();
                        if (!CollUtil.isNotEmpty(gkStatistics)) {
                            for (GkSignalCommunication gkSignalCommunication : gkSignalCommunications) {
                                GkStatistics gkStatistic = new GkStatistics();
                                gkStatistic.setGkSignalId(gkSignalCommunication.getId());
                                gkStatistic.setProductRealNum(0);
                                gkStatistic.setProductNum(0);
                                gkStatistic.setPlanProductNum(list.get(0).getPlanProductNum());
                                gkStatistic.setProductNgNum(0);
                                gkStatistic.setPlanBit(list.get(0).getPlanBit());
                                gkStatistic.setRealBit(0f);
                                gkStatistic.setRuntime(0);
                                gkStatistic.setCreateAt(new Date());
                                gkStatistic.setLastModifyAt(new Date());
                                gkStatisticsMapper.insert(gkStatistic);
                            }
                        } else {
                            Long gkSignalId = null;
                            for (GkSignalCommunication gkSignalCommunication : gkSignalCommunications) {
                                if (gkSignalCommunication.getCommunicationProtocol().equals("PLC-2020-ZP-ZC")) {
                                    GkStatistics gkStatistic = null;
                                    gkSignalId = gkSignalCommunication.getId();
                                    for (GkStatistics statistic : gkStatistics) {
                                        if (statistic.getGkSignalId().longValue() == gkSignalId.longValue()) {
                                            gkStatistic = statistic;
                                        }
                                    }
                                    List<String> nodeNameList = new ArrayList<>();
                                    for (int i = 1; i <= 16; i++) {
                                        String nodeName = "St1.OKCount[" + i + "]";
                                        String nodeName1 = "St1.NGCount[" + i + "]";
                                        String nodeName2 = "St1.CycleTime[" + i + "]";
                                        nodeNameList.add(nodeName);
                                        nodeNameList.add(nodeName1);
                                        nodeNameList.add(nodeName2);
                                    }
                                    ReadByNodeReq readByNodeReq = new ReadByNodeReq();
                                    readByNodeReq.setUid(gkSignalCommunication.getCommunicationProtocol());
                                    ArrayList<NodeDTOV2> nodeDTOV2List1 = new ArrayList<>();
                                    OpcUaList opcUaList = ReadOpcUaNodeInfoTool.GetOpcUaList();
                                    List<OpcUa> uaList = opcUaList.getOpcUaList();
                                    for (OpcUa opcUa : uaList) {
                                        if (opcUa.getUid().equals(gkSignalCommunication.getCommunicationProtocol())) {
                                            List<Node> nodeList = opcUa.getNodeList();
                                            for (Node node : nodeList) {
                                                if (nodeNameList.contains(node.getDisplayName())) {
                                                    NodeDTOV2 nodeDTOV2 = new NodeDTOV2();
                                                    nodeDTOV2.setNodeId(node.getNodeId());
                                                    nodeDTOV2.setNodeName(node.getNodeName());
                                                    nodeDTOV2.setNodeType(node.getNodeType());
                                                    nodeDTOV2.setDisplayName(node.getDisplayName());
                                                    nodeDTOV2List1.add(nodeDTOV2);
                                                }
                                            }
                                        }
                                    }
                                    readByNodeReq.setNodeDTOV2List(nodeDTOV2List1);
                                    Ret<BatchReadDTO> batchReadDTORet = opcUaServiceV2.readDataByNodeList(readByNodeReq);
                                    List<NodeDTOV2> nodeDTOV2List = batchReadDTORet.getData().getDtoList();
                                    if (CollUtil.isNotEmpty(nodeDTOV2List)) {
                                        for (int i = 1; i <= 16; i++) {
                                            if (i == 12) {
                                                for (NodeDTOV2 nodeDTOV2 : nodeDTOV2List) {
                                                    Object nodeValue = nodeDTOV2.getNodeValue();
                                                    if (nodeValue != null) {
                                                        GkStatistics gkStatistics1 = new GkStatistics();
                                                        gkStatistics1.setId(gkStatistic.getId());
                                                        if (nodeDTOV2.getDisplayName().equals("St1.OKCount[12]")) {
                                                            gkStatistics1.setProductNum(Integer.parseInt(nodeValue.toString()));
                                                            if (gkStatistic.getProductNgNum() != null) {
                                                                gkStatistics1.setProductRealNum(gkStatistics1.getProductNum() + gkStatistic.getProductNgNum());
                                                            } else {
                                                                gkStatistics1.setProductRealNum(gkStatistics1.getProductNum());
                                                            }
                                                        }
                                                        if (nodeDTOV2.getDisplayName().equals("St1.NGCount[12]")) {
                                                            gkStatistics1.setProductNgNum(Integer.parseInt(nodeValue.toString()));
                                                            if (gkStatistic.getProductNum() != null) {
                                                                gkStatistics1.setProductRealNum(gkStatistics1.getProductNgNum() + gkStatistic.getProductNum());
                                                            } else {
                                                                gkStatistics1.setProductRealNum(gkStatistics1.getProductNgNum());
                                                            }
                                                        }
                                                        if (nodeDTOV2.getDisplayName().equals("St1.CycleTime[12]")) {
                                                            gkStatistics1.setRealBit(Float.parseFloat(nodeValue.toString()));
                                                        }
                                                        if (nodeDTOV2.getDisplayName().equals("St1.RunTime")) {
                                                            gkStatistics1.setRuntime(Integer.parseInt(nodeValue.toString()));
                                                            GkReservedInfo gkReservedInfo = new GkReservedInfo();
                                                            Integer i1 = Integer.parseInt(nodeValue.toString()) / 60;
                                                            gkReservedInfo.setId(6l);
                                                            gkReservedInfo.setValue(i1.toString() + "分钟");
                                                            gkReservedInfoMapper.edit(gkReservedInfo);
                                                        }
                                                        if (gkStatistics1.getProductNgNum() == null && gkStatistics1.getProductNum() == null && gkStatistics1.getProductRealNum() == null && gkStatistics1.getRealBit() == null && gkStatistics1.getRuntime() == null) {
                                                            continue;
                                                        }
                                                        gkStatisticsMapper.updateInfo(gkStatistics1);
                                                    }
                                                }
                                                continue;
                                            }
                                            String nodeName = "St1.OKCount[" + i + "]";
                                            String nodeName1 = "St1.NGCount[" + i + "]";
                                            String nodeName2 = "St1.CycleTime[" + i + "]";
                                            GkShowStationInfo gkShowStationInfo = new GkShowStationInfo();
                                            for (NodeDTOV2 nodeDTOV2 : nodeDTOV2List) {
                                                Object nodeValue = nodeDTOV2.getNodeValue();
                                                if (nodeValue != null) {
                                                    Long id = new Long(i);
                                                    if (i > 12) {
                                                        id = new Long(i - 1);
                                                    }
                                                    gkShowStationInfo.setId(id);
                                                    if (nodeDTOV2.getDisplayName().equals(nodeName)) {
                                                        // 工位OK数
                                                        gkShowStationInfo.setOkCount(Integer.parseInt(nodeValue.toString()));
                                                    }
                                                    if (nodeDTOV2.getDisplayName().equals(nodeName1)) {
                                                        // 工位NG数
                                                        gkShowStationInfo.setNgCount(Integer.parseInt(nodeValue.toString()));
                                                    }
                                                    if (nodeDTOV2.getDisplayName().equals(nodeName2)) {
                                                        // 工位节拍
                                                        gkShowStationInfo.setCycleTime(Integer.parseInt(nodeValue.toString()));
                                                    }
                                                    if (nodeDTOV2.getDisplayName().equals("DB_RECIPE.NG_CNT")) {
                                                        String value = OpcUATool.getValue(nodeDTOV2);
                                                        GkReservedInfo gkReservedInfo = new GkReservedInfo();
                                                        gkReservedInfo.setValue(value);
                                                        gkReservedInfo.setId(7l);
                                                        gkReservedInfoMapper.edit(gkReservedInfo);
                                                    }
                                                }
                                            }
                                            if (gkShowStationInfo.getNgCount() == null && gkShowStationInfo.getOkCount() == null && gkShowStationInfo.getCycleTime() == null) {
                                                continue;
                                            }
                                            gkShowStationInfoMapper.edit(gkShowStationInfo);
                                        }

                                    }

                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        }
        ).start();
    }

    private void SaveDeleteConfig(List<Long> saveConfigIds, Long connectId) {
        if (CollUtil.isNotEmpty(saveConfigIds)) {
            try {
                List<GkStationConfigurationValues> gkStationConfigurationValuesList = gkStationConfigurationValuesMapper.selectInfoByConfigIdsAndConnectId(saveConfigIds, connectId);
                if (CollUtil.isNotEmpty(gkStationConfigurationValuesList)) {
                    File file = new File("D:/sg/deleteConfigLog.txt");
                    if (!file.exists()) {
                        // 如果文件不存在，则创建文件及其所在的目录
                        file.getParentFile().mkdirs();
                        file.createNewFile();
                    }
                    ObjectMapper objectMapper = new ObjectMapper();
                    String jsonArrayString = objectMapper.writeValueAsString(gkStationConfigurationValuesList);

                    String updatedJsonArrayStringWithPadding = "\n" + jsonArrayString + "\n";

                    try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8, StandardOpenOption.APPEND)) {
                        writer.write(updatedJsonArrayStringWithPadding);
                    } catch (IOException e) {
                        // 处理写入文件出错的异常
                        log.error(e.getMessage());
                    }

                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
    }

    @Autowired
    JdbcTemplate jdbcTemplate;

    private void  judgeJDBC(){
        try {
            jdbcTemplate.execute("select 1 ");
        }catch (Exception e){
            log.error("数据库连接异常：{}",e.getMessage());
            // 终止程序
            System.exit(0);
        }
    }
}
